package dao;

import java.util.ArrayList;
import java.util.List;

import org.hibernate.Query;
import org.hibernate.Session;

import trip.HibernateUtil;
import trip.Route;
import trip.Stop;
import trip.Time_table;
import trip.Trip;

public class Time_tableDAOImpl extends GenericDaoImpl<Time_table>  implements Time_tableDAO {
	public Time_tableDAOImpl(Class<Time_table> type) {
		super(type);
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<Time_table> getByTrip(Trip trip) {
		Session session = null;
		List<Time_table> result = new ArrayList<Time_table>();
		if (trip == null)
			return result;
		try {
			session = HibernateUtil.getFactory().openSession();
			session.beginTransaction();
			Query query = session.createQuery("select tt from Time_table tt "
					+ "where tt.trip = :id order by tt.stop_number asc");
			query.setLong("id", trip.getId());
			result = query.list();
			session.getTransaction().commit();
			return result;
		} finally {
			if (session != null && session.isOpen())
				session.close();
		}
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<Time_table> getByRoute(Route route) {
		Session session = null;
		List<Time_table> result = new ArrayList<Time_table>();
		if (route == null)
			return result;
		try {
			session = HibernateUtil.getFactory().openSession();
			session.beginTransaction();
			Query query = session.createQuery("select tt from Time_table tt "
					+ "where tt.trip.route = :id order by tt.trip asc");
			query.setLong("id", route.getId());
			result = query.list();
			session.getTransaction().commit();
			return result;
		} finally {
			if (session != null && session.isOpen())
				session.close();
		}
	}

	@Override
	public int getVacantSeats(Stop departure, Stop arrival, Trip trip) {
		Session session = null;
		int result = 0;
		if (departure == null || arrival == null || trip == null)
			return result;
		try {
			session = HibernateUtil.getFactory().openSession();
			session.beginTransaction();
			Query query = session.createQuery("select min(tt.vacant_seats) from Time_table tt "
					+ "where tt.stop_number >= (select rs.stop_number from Route_stops rs "
					+ "where rs.route = tt.trip.route and rs.stop = :sin) "
					+ "and tt.stop_number < (select rs.stop_number from Route_stops rs "
					+ "where rs.route = tt.trip.route and rs.stop = :sout) "
					+ "and tt.trip = :tid "
					+ "group by tt.trip")
					.setParameter("sin", departure).setParameter("sout", arrival).setParameter("tid", trip);
			result = (int)query.list().get(0);
			session.getTransaction().commit();
			return result;
		} finally {
			if (session != null && session.isOpen())
				session.close();
		}
	}
}
